﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tecnicas.CasoEstudio.Back.Dominio;
using Tecnicas.CasoEstudio.Repositorio;
using System.Collections;


namespace Tecnicas.CasoEstudio.Back.Persistencia
{
    public class ClienteDataMapper : AbstractDataMapper
    {
        public ClienteDataMapper()
        {             
        }
        

        public override object Insert(DomainObject obj)
        {
            if (typeof(Cliente) != obj.GetType())
                throw new ApplicationException("Este mapper solo opera con objetos del tipo Cliente");

            if (obj.PersistenceId == null)
            {
                obj.PersistenceId = RepositorioVersionado.Instance.GetNextKey();
                obj.PersistenceVersion = 0;
            }

            Cliente cliente = (Cliente)obj;

            cliente.PersistenceIdAlquileres = new ArrayList();
            // se persisten las agregaciones
            AlquilerDataMapper alquilerDataMapper = new AlquilerDataMapper();
            foreach(Alquiler alquiler in cliente.GetAlquileres())
            {
                Alquiler alquilerNew = (Alquiler)alquilerDataMapper.Insert(alquiler);
                cliente.PersistenceIdAlquileres.Add(alquilerNew.PersistenceId);
            } 

            Cliente clienteCopia = this.ClonePlainObject(cliente);

            RepositorioVersionado.Instance.Guardar(clienteCopia, clienteCopia.PersistenceId, clienteCopia.PersistenceVersion, ++clienteCopia.PersistenceVersion);

            cliente.PersistenceVersion++;
            return cliente;
        }
        private Cliente ClonePlainObject(Cliente cliente)
        {
            Cliente clienteCopia = new Cliente(cliente.Nombre);
            clienteCopia.PersistenceId = cliente.PersistenceId;
            clienteCopia.PersistenceVersion = cliente.PersistenceVersion;
            clienteCopia.PersistenceIdAlquileres = cliente.PersistenceIdAlquileres;

            return clienteCopia;
        }
        public override void Delete(long? id, object version)
        {
            RepositorioVersionado.Instance.Eliminar(typeof(Cliente), id, version);
        }
        public override void Delete(DomainObject obj)
        {
            this.Delete(obj.PersistenceId, obj.PersistenceVersion);
        }

        public override DomainObject Find(long? id)
        {
            return (Cliente)RepositorioVersionado.Instance.ObtenerPorId(typeof(Cliente), id);
        }

        public override ArrayList FindAll()
        {
            return RepositorioVersionado.Instance.ObtenerPorTipo(typeof(Cliente));
        }

        public Cliente FindByNombre(string nombre)
        {
            ArrayList lista = RepositorioVersionado.Instance.ObtenerPorAtributo(typeof(Cliente), "Nombre", nombre);
            if (lista.Count == 1)
                return (Cliente)lista[0];
            else
                throw new ApplicationException("Mas de un cliente con dicho nombre");
        }
        
        public ArrayList FindAllByNombre(string name)
        {
            ArrayList lista = RepositorioVersionado.Instance.ObtenerPorAtributo(typeof(Cliente), "Name", name);
            return lista;
        }

    }
}
